﻿namespace Smart.Utils.Security2
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    public class EncryptEngine
    {
        private Smart.Utils.Security2.EncryptionAlgorithm AlgoritmID;
        private bool bWithKey = false;
        private string keyword = "";
        public byte[] Vector;

        public EncryptEngine(Smart.Utils.Security2.EncryptionAlgorithm AlgID, string Key)
        {
            if (Key.Length == 0)
            {
                this.bWithKey = false;
            }
            else
            {
                this.bWithKey = true;
            }
            this.keyword = Key;
            this.AlgoritmID = AlgID;
        }

        public ICryptoTransform GetCryptTransform()
        {
            byte[] bytes = Encoding.ASCII.GetBytes(this.keyword);
            switch (this.AlgoritmID)
            {
                case Smart.Utils.Security2.EncryptionAlgorithm.DES:
                {
                    DES des = new DESCryptoServiceProvider();
                    des.Mode = CipherMode.CBC;
                    if (this.bWithKey)
                    {
                        des.Key = bytes;
                    }
                    this.Vector = des.IV;
                    return des.CreateEncryptor();
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.Rc2:
                {
                    RC2 rc = new RC2CryptoServiceProvider();
                    rc.Mode = CipherMode.CBC;
                    if (this.bWithKey)
                    {
                        rc.Key = bytes;
                    }
                    this.Vector = rc.IV;
                    return rc.CreateEncryptor();
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.Rijndael:
                {
                    Rijndael rijndael = new RijndaelManaged();
                    rijndael.Mode = CipherMode.CBC;
                    if (this.bWithKey)
                    {
                        rijndael.Key = bytes;
                    }
                    this.Vector = rijndael.IV;
                    return rijndael.CreateEncryptor();
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.TripleDes:
                {
                    TripleDES edes = new TripleDESCryptoServiceProvider();
                    edes.Mode = CipherMode.CBC;
                    if (this.bWithKey)
                    {
                        edes.Key = bytes;
                    }
                    this.Vector = edes.IV;
                    return edes.CreateEncryptor();
                }
            }
            throw new CryptographicException("Algorithm " + this.AlgoritmID + " Not Supported!");
        }

        public static bool ValidateKeySize(Smart.Utils.Security2.EncryptionAlgorithm algID, int Lenght)
        {
            switch (algID)
            {
                case Smart.Utils.Security2.EncryptionAlgorithm.DES:
                {
                    DES des = new DESCryptoServiceProvider();
                    return des.ValidKeySize(Lenght);
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.Rc2:
                {
                    RC2 rc = new RC2CryptoServiceProvider();
                    return rc.ValidKeySize(Lenght);
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.Rijndael:
                {
                    Rijndael rijndael = new RijndaelManaged();
                    return rijndael.ValidKeySize(Lenght);
                }
                case Smart.Utils.Security2.EncryptionAlgorithm.TripleDes:
                {
                    TripleDES edes = new TripleDESCryptoServiceProvider();
                    return edes.ValidKeySize(Lenght);
                }
            }
            throw new CryptographicException("Algorithm " + algID + " Not Supported!");
        }

        public Smart.Utils.Security2.EncryptionAlgorithm EncryptionAlgorithm
        {
            get
            {
                return this.AlgoritmID;
            }
            set
            {
                this.AlgoritmID = value;
            }
        }
    }
}

